package com.fingard.dsp.bank.directbank.nnbill01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IGateway;
import com.fingard.dsp.bank.directbank.nnbill01.md5.MD5Util;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.gateway.GatewayOrderQueryServiceLocator;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.gateway.dto.GatewayOrderDetail;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.gateway.dto.GatewayOrderQueryRequest;
import com.fingard.dsp.bank.directbank.nnbill01.wsdl.gateway.dto.GatewayOrderQueryResponse;
import com.fingard.dsp.bank.reqrespobj.gateway.ReqGateway;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.ReqQueryOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.RetAtsQueryOrder;
import com.fingard.text.StringHelper;
import sun.misc.BASE64Encoder;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;

public class NNBill01Gateway extends NNBill01Base implements IGateway {
	@Override
	public HashMap<String, String> GenGwMap(ReqGateway p_reqGateway) throws Exception {
		HashMap<String, String> retMap = new HashMap<String, String>();

		try {
			String ownAct = "";
			if (p_reqGateway.reqHashMap.containsKey("OurBankAccount")) {
				ownAct = p_reqGateway.reqHashMap.get("OurBankAccount");
			}
			ActSetItem actItem = this.getBankConfig().getActSetItemByAny(ownAct, "", "", "*");
			if (actItem != null) {

                boolean isMobile = "1".equals(p_reqGateway.reqHashMap.get("IsMobile"));
                if (isMobile) {
                    WriteBankLogLn("本次请求为移动网关支付请求");
                } else {
                    WriteBankLogLn("本次请求为PC端网关支付请求");
                } 

				// 超时时间
				Date dateStart = Format.DateTime14Format.parse(p_reqGateway.reqHashMap.get("TimeStart"));
				Date dateExpire = Format.DateTime14Format.parse(p_reqGateway.reqHashMap.get("TimeExpire"));
				long timeOut = (dateExpire.getTime() - dateStart.getTime())/1000;
				
				String orderTimeOut = String.valueOf(timeOut);
				String inputCharset = getBankConfig().getMapKeyByValue("charsetMapping", getCharset());
				String orderId = p_reqGateway.reqHashMap.get("RdSeq");
				String orderAmount = StringHelper.amountMultiply100(p_reqGateway.reqHashMap.get("Amount"));
				String orderTime = p_reqGateway.reqHashMap.get("TimeStart");
				String productName = p_reqGateway.reqHashMap.get("Description");
				String payType = p_reqGateway.reqHashMap.get("PayType");
				if (StringHelper.isNullOrEmpty(payType)) {
                    payType = "00";
                }

				String signMsgVal = "";
				signMsgVal = appendParam(signMsgVal, "inputCharset", inputCharset);
				signMsgVal = appendParam(signMsgVal, "pageUrl", actItem.notifyURL);
				signMsgVal = appendParam(signMsgVal, "bgUrl", actItem.returnURL);
                String version = "v2.0";
                if (isMobile) {
                    version =  "mobile1.0";
                }
				signMsgVal = appendParam(signMsgVal, "version", version);

				signMsgVal = appendParam(signMsgVal, "language", "1");
				signMsgVal = appendParam(signMsgVal, "signType", "4");
				signMsgVal = appendParam(signMsgVal, "merchantAcctId",actItem.merchantId);
				signMsgVal = appendParam(signMsgVal, "payerName", "");
				signMsgVal = appendParam(signMsgVal, "payerContactType","");
				signMsgVal = appendParam(signMsgVal, "payerContact", "");
				signMsgVal = appendParam(signMsgVal, "payerIdType", "");
				signMsgVal = appendParam(signMsgVal, "payerId", "");
				signMsgVal = appendParam(signMsgVal, "payerIP", "");
				signMsgVal = appendParam(signMsgVal, "orderId", orderId);
				signMsgVal = appendParam(signMsgVal, "orderAmount", orderAmount);
				signMsgVal = appendParam(signMsgVal, "orderTime", orderTime);
				signMsgVal = appendParam(signMsgVal, "orderTimestamp", "");
				signMsgVal = appendParam(signMsgVal, "productName", productName);
				signMsgVal = appendParam(signMsgVal, "productNum", "");
				signMsgVal = appendParam(signMsgVal, "productId", "");
				signMsgVal = appendParam(signMsgVal, "ext1", p_reqGateway.reqHashMap.get("Attach"));
				signMsgVal = appendParam(signMsgVal, "ext2", "");
                if (isMobile) {
                    signMsgVal = appendParam(signMsgVal, "aggregatePay", "");
                    signMsgVal = appendParam(signMsgVal, "pkgCode ", "");
                    signMsgVal = appendParam(signMsgVal, "period ", "");
                }
                //移动端21
				signMsgVal = appendParam(signMsgVal, "payType", payType);

				signMsgVal = appendParam(signMsgVal, "bankId", "");
				signMsgVal = appendParam(signMsgVal, "cardIssuer", "");
				signMsgVal = appendParam(signMsgVal, "cardNum", "");
                if (!isMobile) {
                    signMsgVal = appendParam(signMsgVal, "remitType", "");
                    signMsgVal = appendParam(signMsgVal, "remitCode", "");
                    signMsgVal = appendParam(signMsgVal, "pid", "");
                } else {
                    signMsgVal = appendParam(signMsgVal, "extDataContent", "");
                }
				signMsgVal = appendParam(signMsgVal, "redoFlag", "");
				signMsgVal = appendParam(signMsgVal, "submitType", "");
				signMsgVal = appendParam(signMsgVal, "orderTimeOut", orderTimeOut);
				signMsgVal = appendParam(signMsgVal, "extDataType", "");
				signMsgVal = appendParam(signMsgVal, "signMsg", "");
				signMsgVal = appendParam(signMsgVal, "referDataType", "");
				signMsgVal = appendParam(signMsgVal, "referData", "");
				
				WriteBankLogLn2("待签名串为:\r\n" + signMsgVal);
				
				StringBuilder sbSignErr = new StringBuilder();

				String signMsg = "";
				boolean useNewSign = getBankConfig().getValueAsBool("useNewSign");
				if (useNewSign) {
                    signMsg = signMsg(signMsgVal, actItem.ownKeyStorePath, actItem.ownKeyPassword);
				} else {
                    byte[] tmpSign = Crypto.sign("RSA", signMsgVal, getCharset(),"PKCS12", "SHA1withRSA", actItem.ownKeyStorePath, actItem.ownKeyPassword, sbSignErr);
                    signMsg = new BASE64Encoder().encode(tmpSign);
				}
				if (signMsg.length() > 0) {
					retMap.put("RespCode", "0");
					retMap.put("RespInfo", "签名成功");
					
					WriteBankLogLn2("签名成功，签名串为:\r\n" + signMsg);
				} else {
					retMap.put("RespCode", "-1");
					retMap.put("RespInfo", "签名失败");
				}
				retMap.put("inputCharset", inputCharset);
				retMap.put("pageUrl", actItem.notifyURL);
				retMap.put("bgUrl", actItem.returnURL);
				retMap.put("version", version);
				retMap.put("language", "1");
				retMap.put("signType", "4");
				retMap.put("merchantAcctId", actItem.merchantId);
				retMap.put("payerName", "");
				retMap.put("payerContactType", "");
				retMap.put("payerContact", "");
				retMap.put("payerIdType", "");
				retMap.put("payerId", "");
				retMap.put("payerIP", "");
				retMap.put("orderId", orderId);
				retMap.put("orderAmount", orderAmount);
				retMap.put("orderTime", orderTime);
				retMap.put("orderTimestamp", "");
				retMap.put("productName", productName);
				retMap.put("productNum", "");
				retMap.put("productId", "");
				retMap.put("productDesc", "");
				retMap.put("ext1", p_reqGateway.reqHashMap.get("Attach"));
				retMap.put("ext2", "");
				retMap.put("payType", payType);
				retMap.put("bankId", "");
				retMap.put("cardIssuer", "");
				retMap.put("cardNum", "");
                if (!isMobile) {
                    retMap.put("remitType", "");
                    retMap.put("remitCode", "");
                    retMap.put("pid", "");
                }
				retMap.put("redoFlag", "");
				retMap.put("sumitType", "");
				retMap.put("orderTimeOut", orderTimeOut);
				retMap.put("extDataType", "");
				retMap.put("extDataContent", "");
				retMap.put("signMsg", signMsg);
				retMap.put("referDataType", "");
				retMap.put("referData", "");
                String url = bankFront.getUrl("orderGW");
                if (isMobile) {
                    url = bankFront.getUrl("orderGWByMobile");
                }
				retMap.put("NNBillGatewayService", url);

				WriteBankLogLn2("人民币网关支付提交服务地址:" + url);
			} else {
				retMap.put("RespCode", "-1");
				retMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息!");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retMap.put("RespCode", "-1");
			retMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retMap;
	}

	@Override
	public RetAtsQueryOrder queryGWPay(ReqQueryOrder p_req) throws Exception {
		RetAtsQueryOrder retAts = new RetAtsQueryOrder();
		retAts.rdSeq = p_req.rdSeq;
		
		try{
			ActSetItem actItem = this.getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "*");
			if(actItem != null){
				LinkedHashMap<String,String> params = new LinkedHashMap<String,String>();
                boolean isMobile = "1".equals(p_req.isMobile);
				params.put("inputCharset", "1");
                String version = "v2.0";
                if (isMobile) {
                    version =  "mobile1.0";
                }
				params.put("version", version);

				params.put("signType", "1");

				params.put("merchantAcctId", actItem.merchantId);
				params.put("queryType", "0");
				params.put("queryMode", "1");
				params.put("startTime", "");
				params.put("endTime", "");
				params.put("requestPage", "");
				params.put("orderId", p_req.rdSeq);
				params.put("key", actItem.saltKey);
				
				String signMsgParam = convertMapToStr(params);
                WriteBankLogLn("加签原始数据：" + signMsgParam);
				String signMsg = MD5Util.md5Hex(signMsgParam.getBytes(getCharset())).toUpperCase();
				params.put("signMsg", signMsg);
				
				GatewayOrderQueryRequest queryRequest = new GatewayOrderQueryRequest();
				
				queryRequest.setInputCharset(params.get("inputCharset"));
				queryRequest.setVersion(params.get("version"));
				queryRequest.setSignType(Integer.parseInt(params.get("signType")));
				queryRequest.setMerchantAcctId(params.get("merchantAcctId"));
				queryRequest.setQueryType(Integer.parseInt(params.get("queryType")));
				queryRequest.setQueryMode(Integer.parseInt(params.get("queryMode")));
				queryRequest.setOrderId(params.get("orderId"));
				queryRequest.setStartTime(params.get("startTime"));
				queryRequest.setEndTime(params.get("endTime"));
				queryRequest.setRequestPage(params.get("requestPage"));
				queryRequest.setSignMsg(params.get("signMsg"));

				String sendRUL = bankFront.getUrl("queryGW");
				WriteBankLogLn2("人民币/移动网关支付查询服务地址为:" + sendRUL);
                String req = signMsgParam + "&signMsg" + signMsg;
                WriteBankLogStep2(req);

				GatewayOrderQueryServiceLocator locator = new GatewayOrderQueryServiceLocator(sendRUL);
				GatewayOrderQueryResponse queryResponse = locator.getgatewayOrderQuery().gatewayOrderQuery(queryRequest);
				
				retAts.respCode = "0";
				String errCode = queryResponse.getErrCode();
				if (errCode != null && !"".equals(errCode)) {
					retAts.transState = errCode;
					retAts.payInfoCode = errCode;
				} else {
					GatewayOrderDetail[] orders = queryResponse.getOrders();
					for (int i = 0; i < orders.length; i++) {
						GatewayOrderDetail detail = orders[i];
						
						retAts.transState = detail.getPayResult();
						retAts.payInfoCode = detail.getPayResult();
						retAts.outTransID = detail.getDealId();
					}
				}
			} else {
				retAts.respCode = "-1";
				retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息";
			}
		} catch(Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		return retAts;
	}
}
